<?php

declare(strict_types=1);

namespace app\home\controller;

use app\BaseController;
use app\common\model\Config as ConfigModel;
use app\common\model\Post\Cate as CateModel;
use app\common\model\Post\Post as PostModel;
use app\common\model\User\User as UserModel;
use app\common\model\User\Record as RecordModel;
use app\common\model\Collect as CollectModel;
use app\common\model\Post\Comment as CommentModel;
use app\common\validate\Post\Post as PostValiDate;
use think\exception\ValidateException;
use app\common\validate\User\Record as RecordValiDate;

class Post extends BaseController
{
    // 设置控制器中间件
    protected $middleware = [
        \app\home\middleware\LoginAuth::class => ['except'     => ['info']],
    ];
    protected function initialize()
    {
        $this->PostModel = new PostModel();
        $this->CommentModel = new CommentModel();
        $this->UserModel = new UserModel();
        $this->CollectModel = new CollectModel();
        $this->RecordModel = new RecordModel();
    }
    // 新增帖子
    public function add()
    {
        $LoginUser = $this->request->LoginUser;
        if ($this->request->isPost()) {
            $vercode = $this->request->param('vercode');
            $user = UserModel::find($LoginUser['id']);
            if (!$user) {
                cookie('LoginUser', null);
                $this->error('非法登录', (string)url('/home/index/login'));
            }
            if (!captcha_check($vercode)) {
                $this->error('验证码输入错误，请重新输入');
            }
            $params = $this->request->param();
            // 开启事务操作
            UserModel::startTrans();
            PostModel::startTrans();
            RecordModel::startTrans();
            /* 
                用户表 更新积分 1 save()
                帖子   新增帖子 0
                消费记录 新增消费积分记录
            */
            // 接收帖子状态再查询config表配置项
            $StatePoint = ConfigModel::where(['key' => "PostState{$params['state']}"])->value('value');
            // 悬赏积分+帖子状态积分
            $Point = bcadd((string)$params['point'], (string)$StatePoint);
            // 扣去后的用户所剩积分
            $point = bcsub((string)$LoginUser['point'], (string)$Point);
            if ($point < 0) {
                $this->error('积分不足，请充值');
            }
            // 封装 更新用户表的数据
            $UserData = [
                'point' => $point
            ];
            // 执行更新操作
            $UserStatus = $user->save($UserData);
            // 判断是否更新成功
            if ($UserStatus === FALSE) {
                $this->error('用户积分更新失败');
            }
            //帖子表数据操作
            //封装帖子表的数据
            $PostData = [
                'title' => $params['title'],
                'content' => $params['content'],
                'point' => $params['point'],
                'state' => $params['state'],
                'userid' => $user['id'],
                'cateid' => $params['cateid']
            ];
            // 验证数据的规则有无问题
            try {
                validate(PostValiDate::class)->check($PostData);
            } catch (ValidateException $e) {
                $this->error($e->getMessage());
            }
            // 执行插入操作
            $PostStatus = $this->PostModel->save($PostData);
            // 判断插入是否成功 失败则回滚用户表积分
            if ($PostStatus === FALSE) {
                UserModel::rollback();
                $this->error('帖子发表失败');
            }

            //消费记录表数据操作
            // 封装数据
            $RecordData = [
                'point' => $Point,
                'content' => "您发表帖子：{$PostData['title']}消费了{$Point}积分",
                'state' => 1,
                'userid' => $user['id']
            ];
            // 验证数据
            try {
                validate(RecordValiDate::class)->check($RecordData);
            } catch (ValidateException $e) {
                UserModel::rollback();
                PostModel::rollback();
                $this->error($e->getMessage());
            }
            // 执行插入
            $RecordStatus = $this->RecordModel->save($RecordData);
            // 判断是否成功，失败则回滚用户积分及帖子插入操作
            if ($RecordStatus === FALSE) {
                UserModel::rollback();
                PostModel::rollback();
                $this->error('新增消费记录失败');
            }
            // 总判断
            if ($UserStatus === FALSE || $PostStatus === FALSE || $RecordStatus === FALSE) {
                // 回滚
                UserModel::rollback();
                PostModel::rollback();
                RecordModel::rollback();
                $this->error('发表失败');
            } else {
                // 提交事务
                UserModel::commit();
                PostModel::commit();
                RecordModel::commit();
                $this->success('发表成功', (string)url('/home/index/index'));
            }
        }

        // 查询分类数据
        $CateList = CateModel::order('weigh', 'desc')->limit(6)->select();

        // 调用Post模型查询状态方法
        $StateList = $this->PostModel->state();

        return view('', [
            'CateList' => $CateList,
            'StateList' => $StateList
        ]);
    }
    // 删除帖子
    public function del()
    {
        $LoginUser = $this->request->LoginUser;
        if ($this->request->isAjax()) {
            // 获取帖子id
            $postid = $this->request->param('postid');
            // 查询帖子
            $post = $this->PostModel->find($postid);
            if (!$post) {
                $this->error('帖子不存在');
            }
            
            // 开启事务操作
            PostModel::startTrans();
            CommentModel::startTrans();
        
            // 评论表
            $CommentState=$this->CommentModel->destroy(['postid'=>$postid]);
            if ($CommentState === FALSE) {
                $this->error('删除评论失败');
            }
            
            // 执行软删除
            $result = $this->PostModel->destroy($postid);
            if ($result === FALSE) {
                CommentModel::rollback();
                $this->error('删除失败');
            }
            if($result===false || $CommentState===false){
                PostModel::rollback();
                CommentModel::rollback();
                $this->error('删除帖子失败');
            }else{
                PostModel::commit();
                CommentModel::commit();
                $this->success('删除帖子成功', (string)url('/home/index/index'));
            }
        }
    }
    // 帖子编辑
    public function edit()
    {
        // 接收帖子id
        $postid = $this->request->param('postid');
        $LoginUser = !empty(cookie('LoginUser')) ? json_decode(cookie('LoginUser'), true) : [];
        $userid = !empty($LoginUser['id']) ? $LoginUser['id'] : 0;
        if ($this->request->isPost()) {
            $post = $this->PostModel->find($postid);
            $user = UserModel::find($userid);
            if (!$post) {
                $this->error('帖子不存在,请重新选择');
            }
            if (!$user) {
                $this->error('请先登录');
            }

            if ($user['id'] != $post['userid']) {
                $this->error('您没有权限修改他人帖子');
            }

            $params = $this->request->param();

            if (!captcha_check($params['vercode'])) {
                $this->error('验证码错误，请重新输入');
            }
            // 封装数据
            $data = [
                'cateid' => $params['cateid'],
                'title' => $params['title'],
                'content' => $params['content']
            ];
            // 验证数据
            try {
                validate(PostValiDate::class)->scene('edit')->check($data);
            } catch (ValidateException $e) {
                $this->error($e->getMessage());
            }

            $result = $post->save($data);

            if ($result !== FALSE) {
                $this->success('更新帖子成功', (string)url('/home/post/info', ['postid' => $postid]));
            } else {
                $this->error('更新帖子失败');
            }
        }
        $post = $this->PostModel->withJoin(['type'])->find($postid);
        // 查询分类数据
        $CateList = CateModel::order('weigh', 'desc')->limit(6)->select();

        // 调用Post模型查询状态方法
        $StateList = $this->PostModel->state();

        return view('', [
            'CateList' => $CateList,
            'StateList' => $StateList,
            'post' => $post,
        ]);
    }
    // 帖子详情
    public function info()
    {
        // 获取登录用户的cookie
        $LoginUser = !empty(cookie('LoginUser')) ? json_decode(cookie('LoginUser'), true) : [];
        // 将cookie里的用户id赋值
        $userid = !empty($LoginUser['id']) ? $LoginUser['id'] : 0;
        // 获取帖子的id
        $postid  = $this->request->param('postid');
        // 查询帖子详情，type=>帖子分类，user=>连表查询
        $post = $this->PostModel::withjoin(['user', 'type'])->where(['post.id' => $postid])->find();
        if (!$post) {
            $this->error('数据异常，请重新选择');
        }
        $VisitArr = explode(',', (string)$post['visit']);
        $VisitArr = array_filter($VisitArr);
        // 如果登录用户id存在
        if ($userid) {
            // 如果登录用户id不存在数组里则追加进数组里
            if (!in_array($userid, $VisitArr)) {
                $VisitArr[] = $userid;
                $VisitStr = implode(',', $VisitArr);
                $this->PostModel->where('id', $postid)->update(['visit' => $VisitStr]);
            }
        }
        // 重新查询一遍，更新浏览量字段
        $post = $this->PostModel::withjoin(['user', 'type'])->where(['post.id' => $postid])->find();
        //查询评论数据
        $CommentList = CommentModel::withJoin(['user'])->where(['postid' => $post['id']])->order('id', 'asc')->order('level', 'asc')->select();
        $CommentList = CommentTree($CommentList, 0, $LoginUser);
        //查询当前用户是否收藏该帖子
        $collect = CollectModel::where(['userid' => $userid, 'postid' => $postid])->find();
        // 本周热议
        $PostList =PostModel::whereWeek('createtime')->select()->order('comment_count','desc');
        return view('', [
            'post' => $post,
            'userid' => $userid,
            'LoginUser' => $LoginUser,
            'collect' => $collect,
            'CommentList' => $CommentList,
            'PostList' =>$PostList
        ]);
    }
}
